﻿#include "Mesh.h"
#include "MeshTool.h"

void Mesh::BuildFaceTopo(const std::map<std::string, UInt8>& bnd_name_id)
{
  MeshTool::BuildFaceTopo(*this, bnd_name_id);
}

std::pair<ArrayHandle<UInt8>, ArrayHandle<typename Mesh::FaceInfo>> Mesh::FlatBoundaryInfo(
  const std::map<std::string, UInt8>& bnd_name_id)
{
  //std::pair<ArrayHandle<UInt8>, ArrayHandle<FaceInfo>> boundary_info;

  std::vector<FaceInfo> element_side;
  std::vector<UInt8> bc_type;

  auto valid_sideset_name = [](decltype(GetElementSide()) bc_element_side) -> std::string
  {
    std::stringstream ss;
    ss << "[";
    for (auto& var : bc_element_side)
    {
      ss << var.first << ",";
    }
    ss << "]";
    return ss.str();
  };

  auto& bc_element_side = GetElementSide();

  for (auto& var : bnd_name_id)
  {
    auto& sideset_name = var.first;
    try
    {
      void(_element_sides.at(sideset_name));
    }
    catch (const std::exception&)
    {
      Error("side set:",
            sideset_name,
            ",在网格不存在,可用的side sets: ",
            valid_sideset_name(bc_element_side));
    }

    auto& ele_side = bc_element_side[sideset_name];
    for (auto& face_info : ele_side)
    {
      element_side.push_back(face_info);
      bc_type.push_back(bnd_name_id.at(sideset_name));
    }
  }

  ArrayHandle<FaceInfo> element_side_array = vtkm::cont::make_ArrayHandle(element_side);
  ArrayHandle<UInt8> bc_array = vtkm::cont::make_ArrayHandle(bc_type);
  return { bc_array, element_side_array };
}

const vtkm::cont::Field& Mesh::GetField(const std::string& name) const
{
  try
  {
    return _data_set.GetField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}

const vtkm::cont::Field& Mesh::GetCellField(const std::string& name) const
{
  try
  {
    return _data_set.GetCellField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}

const vtkm::cont::Field& Mesh::GetPointField(const std::string& name) const
{
  try
  {
    return _data_set.GetPointField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}


vtkm::cont::Field& Mesh::GetField(const std::string& name)
{
  try
  {
    return _data_set.GetField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}

vtkm::cont::Field& Mesh::GetCellField(const std::string& name)
{
  try
  {
    return _data_set.GetCellField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}

vtkm::cont::Field& Mesh::GetPointField(const std::string& name)
{
  try
  {
    return _data_set.GetPointField(name);
  }
  catch (const std::exception& e)
  {
    Error(e.what());
  }
}
